
#ifndef LOGGER_H
#define LOGGER_H

#include "NoCopy.h"

#include <pthread.h>

#include <log4cpp/Appender.hh>
#include <log4cpp/Category.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/RollingFileAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Priority.hh>
#include <string>

using namespace log4cpp;
//拼接msg
#define  MSG(msg) std::string("[").append(__FILE__).append(":")\
         .append(__func__).append(":").append(std::to_string(__LINE__))\
         .append("]").append(msg).c_str()

#define LogInfo(msg) l::Logger::getInstance()->info(MSG(msg))
#define LogError(msg) l::Logger::getInstance()->error(MSG(msg))
#define LogWarn(msg) l::Logger::getInstance()->error(MSG(msg)) 
#define LogDebug(msg) l::Logger::getInstance()->debug(MSG(msg))

//log4cpp单例模式
namespace l
{
    class Logger
        :public NoCopy
    {
    public:

        static Logger* getInstance() {

            pthread_once(&ms_onceControl, initRoutine);

            return ms_instance;
        }

        void warn(const char* msg) {
            m_category.warn(msg);
        }

        void error(const char* msg) {
            m_category.error(msg);
        }

        void debug(const char* msg) {
            m_category.debug(msg);
        }

        void info(const char* msg) {
            m_category.info(msg);
        }

    private:

        //私有构造函数和析构函数
        Logger()
            :m_category(Category::getInstance("CloudDisk"))
        {
            //回卷文件输出器
            //new一个输出器
            RollingFileAppender* appender = new RollingFileAppender("rolling", "./log/CouldDisk.log", 1024 * 1024, 3);
            //new一个格式器
            PatternLayout* layout = new PatternLayout();
            //自定义格式器
            layout->setConversionPattern("%c %d [%p] %m%n");
            //输出器绑定格式器
            appender->setLayout(layout);

            //设置优先级(添加过滤器),记录器绑定输出器
            m_category.setPriority(Priority::DEBUG);
            m_category.addAppender(appender);

        }

        ~Logger() {
            Category::shutdown();
        }

        static void destroy() {
            if (ms_instance != nullptr) {
                delete ms_instance;
                ms_instance = nullptr;
            }

        }

        static void initRoutine() {
            if (ms_instance == nullptr) {
                ms_instance = new Logger();
            }

            atexit(destroy);
        }

    private:
        //私有记录器
        Category& m_category;
        static pthread_once_t ms_onceControl;
        static Logger* ms_instance;
    };//end of class Logger;
    //静态成员初始化
    pthread_once_t Logger::ms_onceControl = PTHREAD_ONCE_INIT;
    Logger* Logger::ms_instance = Logger::getInstance();

}//end of namespace l


#endif
